package org.cancerregulome.redi.websvc.model;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.jdbc.core.JdbcTemplate;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.Iterator;
import java.util.Properties;
import java.util.logging.Logger;

import static org.systemsbiology.google.visualization.datasource.JdbcTemplateHelper.getJdbcTemplate;

/**
 * @author hrovira
 */
public class DatasetModel {
    private static final Logger log = Logger.getLogger(DatasetModel.class.getName());

    private final File baseDir;
    private final File rediConfig;

    private String id;
    private JSONObject jsonModel;
    private JdbcTemplate jdbcTemplate;

    public DatasetModel(File baseDir, File rediConfig) throws Exception {
        this.baseDir = baseDir;
        this.rediConfig = rediConfig;
        this.id = this.baseDir.getName();

        this.updateModel();
    }

    protected void updateModel() {
        try {
            this.jsonModel = new JSONObject();
            this.jsonModel.put("label", this.baseDir.getName());

            String datasetJsonPath = this.baseDir.getPath() + "/dataset.json";
            BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(datasetJsonPath)));
            StringBuilder builder = new StringBuilder();
            String line = "";
            while (line != null) {
                line = reader.readLine();
                if (line != null) {
                    builder.append(line);
                }
            }

            this.jsonModel = new JSONObject(builder.toString());
            if (this.jsonModel.has("id")) this.id = this.jsonModel.getString("id");

            if (this.rediConfig != null && this.rediConfig.exists()) {
                Properties p = new Properties();
                p.load(new FileInputStream(this.rediConfig));
                String host = p.getProperty("host", "localhost");
                String port = p.getProperty("port", "3306");
                String classname = p.getProperty("jdbc-classname", "com.mysql.jdbc.Driver");
                String jdbcsuffix = p.getProperty("jdbc-url-prefix", "jdbc:mysql");

                JSONObject jdbc = new JSONObject();
                jdbc.put("classname", classname);
                jdbc.put("username", "REDI");
                jdbc.put("jdbcurl", jdbcsuffix + "://" + host + ":" + port + "/" + this.id);

                this.jdbcTemplate = getJdbcTemplate(jdbc);
            }
        } catch (Exception e) {
            log.warning(e.getMessage());
        }
    }

    public JdbcTemplate JDBC() {
        return jdbcTemplate;
    }

    public String ID() {
        return id;
    }

    public JSONObject JSON() {
        return jsonModel;
    }

    public JSONObject JSONwithURIs(String uri) throws JSONException {
        JSONObject json = new JSONObject(jsonModel.toString());
        json.put("uri", uri);

        Iterator<String> keys = json.keys();
        while (keys.hasNext()) {
            String key = keys.next();
            Object obj = json.get(key);
            if (obj instanceof JSONArray) {
                JSONArray array = (JSONArray) obj;
                for (int i = 0; i < array.length(); i++) {
                    JSONObject item = array.getJSONObject(i);
                    if (item.has("table")) {
                        String tablename = item.getString("table");
                        item.put("tableName", tablename);
                        item.put("table", uri + "/datasources/" + tablename);
                    }
                    if (item.has("graph")) {
                        String graphname = item.getString("graph");
                        item.put("graphName", graphname);
                        item.put("graph", uri + "/graphs/" + graphname);
                    }
                }
            }
        }

        return json;
    }

    public JSONObject LiteJSON() throws JSONException {
        JSONObject json = new JSONObject(jsonModel.toString());

        Iterator<String> keys = json.keys();
        while (keys.hasNext()) {
            String key = keys.next();
            Object obj = json.get(key);
            if (obj instanceof JSONObject) {
                json.remove(key);
            }
        }
        return json;
    }

}
